package Model;

import java.util.ArrayList;
import java.util.Iterator;

public class TaskTreeIterator implements Iterator<Task>
{

    private String typeofTree; //either "Single" or "Periodic" or "Complex". This helps deligate the proper code execution for the iterator
    private Task current;
    private Task head;
    private boolean foundItStatusInSearch;
    
    //--------------------------------------------------------------------------------------------------------
    //--------------------------------------------------------------------------------------------------------

    public TaskTreeIterator(Task head,String type) //Assume head is the most top top of the tree.
    {
        typeofTree = type;
        this.head = head;
        current = this.head;
        foundItStatusInSearch=false;
    }

    //--------------------------------------------------------------------------------------------------------
    //--------------------------------------------------------------------------------------------------------
    
    public String getTypeofTree() 
    {
		return typeofTree;
	}
    
    //--------------------------------------------------------------------------------------------------------
    //--------------------------------------------------------------------------------------------------------

	public void setTypeofTree(String typeofTree) 
	{
		this.typeofTree = typeofTree;
	}

    //--------------------------------------------------------------------------------------------------------
    //--------------------------------------------------------------------------------------------------------
	
	public Task getHead() 
	{
		return head;
	}
	
    //--------------------------------------------------------------------------------------------------------
    //--------------------------------------------------------------------------------------------------------

	public void setHead(Task head) 
	{
		this.head = head;
	}
	
    //--------------------------------------------------------------------------------------------------------
    //--------------------------------------------------------------------------------------------------------

	public boolean isFoundItStatusInSearch() 
	{
		return foundItStatusInSearch;
	}
	
    //--------------------------------------------------------------------------------------------------------
    //--------------------------------------------------------------------------------------------------------

	public void setFoundItStatusInSearch(boolean foundItStatusInSearch) 
	{
		this.foundItStatusInSearch = foundItStatusInSearch;
	}
	
    //--------------------------------------------------------------------------------------------------------
    //--------------------------------------------------------------------------------------------------------

	public void setCurrent(Task current) 
	{
		this.current = current;
	}
	
    //--------------------------------------------------------------------------------------------------------
    //--------------------------------------------------------------------------------------------------------
    
    public Task getCurrent()
    {
    	return current;
    }
    
    //--------------------------------------------------------------------------------------------------------
    //--------------------------------------------------------------------------------------------------------

	public boolean hasNext()
    {
        //safety check incase someone tries to iterate a non-complex Task tree
        if(typeofTree.equals("Single"))
        {
        	foundItStatusInSearch=false;
            return false;
        }

        //safety check incase someone tries to iterate a non-complex Task tree
        else if(typeofTree.equals("Periodic"))
        {
        	foundItStatusInSearch=false;
            return false;
        }

        else if(typeofTree.equals("Complex"))
        {
             if(head.getSubtasks().size()==0)
             {
             	foundItStatusInSearch=false;
                return false;
             }

             else
             {
                Task searchResult = recursivePreorderTreeChecker(head);//Assume head is the most top top of the tree.

                if(searchResult != null)//we found a next
                {
                	foundItStatusInSearch=false;
                    return true;
                }

                else //we did NOT find a next
                {
                	//System.out.println("error 4");
                	foundItStatusInSearch=false;
                    return false;
                }
             }
        }

        else //error case..
        {
        	//System.out.println("error 5");
            return false;
        }
    }

    //--------------------------------------------------------------------------------------------------------
    //--------------------------------------------------------------------------------------------------------

    private Task recursivePreorderTreeChecker(Task subTask)
    {
        if(subTask.getSubtasks().size()>0)
        {
            for (Task loopTask : subTask.getSubtasks())  // for each loop
            {                
                //checking case
                if(current == loopTask) //found the CURRENT pointer, so now lets look if theirs a next one...
                {
                    foundItStatusInSearch=true;
                }
                
                else if(current==subTask)
                {
                	foundItStatusInSearch=true;
                	return loopTask;
                }

                else if (foundItStatusInSearch)
                {
                    return loopTask; //returning pointer to the NEXT node
                }

                //recursive case
                Task temp = recursivePreorderTreeChecker(loopTask); //recursion is here.
                
                if(temp==null)
                {
                	continue; //move to the next itteration of loop
                }

                else if (temp!=null)
                {
                	return temp; //it means we have actually found a next one... so we return it and end the recursion.
                }
                //if it reaches HERE, then it will continue with the next child (if any) in the loop, otherwise it will exit and return null
            }//end of for-each loop  
            return null;
        }//end of if statement where children are >0
        
        else if(foundItStatusInSearch && subTask.getSubtasks().size()==0 && current==subTask )
        {
        	return null;
        }

        else if (subTask.getSubtasks().size()==0 && current==subTask)
        {
            foundItStatusInSearch=true;
            return null;
        }
        return null; //left here during the second...
    }

    //--------------------------------------------------------------------------------------------------------
    //--------------------------------------------------------------------------------------------------------

    public void remove()
    {
    	
    }

    //--------------------------------------------------------------------------------------------------------
    //--------------------------------------------------------------------------------------------------------

    public Task next()
    {
        //safety check incase someone tries to iterate a non-complex Task tree
        if(typeofTree.equals("Single"))
        {
        	foundItStatusInSearch=false;
            return null;
        }

        //safety check incase someone tries to iterate a non-complex Task tree
        else if(typeofTree.equals("Periodic"))
        {
        	foundItStatusInSearch=false;
            return null;
        }

        else if(typeofTree.equals("Complex"))
        {
           if(head.getSubtasks().size()==0)
           {
        	   foundItStatusInSearch=false;
                 return null;
           }

           else
           {
              if(hasNext())//we found a next
              {
                  Task searchResult = recursivePreorderTreeChecker(head);//Assume head is the most top top of the tree.
                  //fatherOfCurrent = current;
                  current = searchResult;
                  foundItStatusInSearch=false;
                  return current;
              }

              else //we did NOT find a next. should try to throw exception (setup later...)
              {
            	  foundItStatusInSearch=false;
                    return null;
              }
           }
        }

        else 
        {
        	foundItStatusInSearch=false;
            return null;
        }
    }

    //--------------------------------------------------------------------------------------------------------
    //--------------------------------------------------------------------------------------------------------
}
